<html lang="zh-CN"><head><meta charset="UTF-8"><style>.nodata  main {width:1000px;margin: auto;}</style></head><body class="nodata " style=""><div class="main_father clearfix d-flex justify-content-center " style="height:100%;"> <div class="container clearfix " id="mainBox"><main><div class="blog-content-box">
<div class="article-header-box">
<div class="article-header">
<div class="article-title-box">
<h1 class="title-article" id="articleContentId">(C卷,100分)- 考勤信息（Java & JS & Python & C）</h1>
</div>
</div>
</div>
<div id="blogHuaweiyunAdvert"></div>

        <div id="article_content" class="article_content clearfix">
        <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
        <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-044f2cf1dc.css">
                <div id="content_views" class="htmledit_views">
                    <h4 id="main-toc">题目描述</h4> 
<p>公司用一个字符串来表示员工的出勤信息</p> 
<ul><li>absent&#xff1a;缺勤</li><li>late&#xff1a;迟到</li><li>leaveearly&#xff1a;早退</li><li>present&#xff1a;正常上班</li></ul> 
<p>现需根据员工出勤信息&#xff0c;判断本次是否能获得出勤奖&#xff0c;能获得出勤奖的条件如下&#xff1a;</p> 
<ul><li>缺勤不超过一次&#xff1b;</li><li>没有连续的迟到/早退&#xff1b;</li><li>任意连续7次考勤&#xff0c;缺勤/迟到/早退不超过3次。</li></ul> 
<p></p> 
<h4 id="%E8%BE%93%E5%85%A5%E6%8F%8F%E8%BF%B0">输入描述</h4> 
<p>用户的考勤数据字符串</p> 
<ul><li>记录条数 &gt;&#61; 1&#xff1b;</li><li>输入字符串长度 &lt; 10000&#xff1b;</li><li>不存在非法输入&#xff1b;</li></ul> 
<p>如&#xff1a;</p> 
<blockquote> 
 <p>2<br /> present<br /> present absent present present leaveearly present absent</p> 
</blockquote> 
<p></p> 
<h4 id="%E8%BE%93%E5%87%BA%E6%8F%8F%E8%BF%B0">输出描述</h4> 
<p>根据考勤数据字符串&#xff0c;如果能得到考勤奖&#xff0c;输出”true”&#xff1b;否则输出”false”&#xff0c;<br /> 对于输入示例的结果应为&#xff1a;</p> 
<blockquote> 
 <p>true false</p> 
</blockquote> 
<p></p> 
<h4 id="%E7%94%A8%E4%BE%8B">用例</h4> 
<table border="1" cellpadding="1" cellspacing="1" style="width:500px;"><tbody><tr><td style="width:86px;">输入</td><td style="width:412px;">2<br /> present<br /> present present</td></tr><tr><td style="width:86px;">输出</td><td style="width:412px;">true<br /> true</td></tr><tr><td style="width:86px;">说明</td><td style="width:412px;">无</td></tr></tbody></table> 
<table border="1" cellpadding="1" cellspacing="1" style="width:500px;"><tbody><tr><td style="width:86px;">输入</td><td style="width:412px;">2<br /> present<br /> present absent present present leaveearly present absent</td></tr><tr><td style="width:86px;">输出</td><td style="width:412px;">true<br /> false</td></tr><tr><td style="width:86px;">说明</td><td style="width:412px;">无</td></tr></tbody></table> 
<h4 id="%E9%A2%98%E7%9B%AE%E8%A7%A3%E6%9E%90">题目解析</h4> 
<p>本题需要注意下</p> 
<blockquote> 
 <p>没有连续的迟到/早退&#xff1b;</p> 
</blockquote> 
<p>根据考友反馈&#xff0c;连续的迟到/早退&#xff0c;应该指&#xff1a;本次是迟到或早退&#xff0c;上次也是迟到或早退。</p> 
<p>比如&#xff0c;本次是迟到&#xff0c;上次是早退&#xff0c;则也算是&#xff1a;连续的迟到/早退</p> 
<p></p> 
<p>本题主要难点在于如果统计”任意连续7次考勤“中的缺勤/迟到/早退次数。</p> 
<p>这里我们可以使用滑动窗口&#xff0c;且滑窗窗口的长度最大为7</p> 
<ul><li>当滑窗右边界索引R &lt; 7 时&#xff0c;则滑窗长度 &#61; R &#43; 1</li><li>当滑窗右边界索引R &gt;&#61; 7时&#xff0c;则滑窗长度 &#61; 7&#xff0c;同时能推导出滑窗左边界索引L为 &#61; R - 6</li></ul> 
<p>如下图所示</p> 
<p><img alt="" height="262" src="https://img-blog.csdnimg.cn/cd324818572a49428a1238642589a118.png" width="614" /></p> 
<p> 我们只要计算出滑窗内部 present 次数&#xff0c;即可通过&#xff1a;</p> 
<blockquote> 
 <p>滑窗长度  - present次数 &#61; 任意连续7次考勤中的缺勤/迟到/早退次数</p> 
</blockquote> 
<p></p> 
<h4 style="background-color:transparent;">JavaScript算法源码</h4> 
<pre><code class="language-javascript">const rl &#61; require(&#34;readline&#34;).createInterface({ input: process.stdin });
var iter &#61; rl[Symbol.asyncIterator]();
const readline &#61; async () &#61;&gt; (await iter.next()).value;
 
void (async function () {
  const n &#61; parseInt(await readline());
  const records &#61; [];
 
  for (let i &#61; 0; i &lt; n; i&#43;&#43;) {
    records.push((await readline()).split(&#34; &#34;));
  }
 
  getResult(records);
})();
 
function getResult(records) {
  for (let record of records) console.log(isAward(record));
}
 
function isAward(record) {
  // 总缺勤次数
  let absent &#61; 0;
 
  // 滑窗内正常上班的次数
  let present &#61; 0;
 
  // 记录前一次的考勤记录
  let preRecord &#61; &#34;&#34;;
 
  for (let i &#61; 0; i &lt; record.length; i&#43;&#43;) {
    // 滑窗长度最大为7&#xff0c;如果超过7&#xff0c;则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
    // 如果失去部分是present&#xff0c;则更新滑窗内present次数
    if (i &gt;&#61; 7) {
      if (&#34;present&#34; &#61;&#61; record[i - 7]) present--;
    }
 
    // 当前的考勤记录
    const curRecord &#61; record[i];
 
    switch (curRecord) {
      case &#34;absent&#34;:
        // 缺勤不超过一次
        if (&#43;&#43;absent &gt; 1) return false;
        break;
      case &#34;late&#34;:
      case &#34;leaveearly&#34;:
        // 没有连续的迟到/早退
        if (&#34;late&#34; &#61;&#61; preRecord || &#34;leaveearly&#34; &#61;&#61; preRecord) return false;
        break;
      case &#34;present&#34;:
        present&#43;&#43;;
        break;
    }
 
    preRecord &#61; curRecord;
 
    // 任意连续7次考勤&#xff0c;缺勤/迟到/早退不超过3次, 相当于判断&#xff1a; 滑窗长度 - present次数 &lt;&#61; 3
    const window_len &#61; Math.min(i &#43; 1, 7);
    if (window_len - present &gt; 3) return false;
  }
 
  return true;
}</code></pre> 
<h4>Java算法源码</h4> 
<pre><code class="language-java">import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc &#61; new Scanner(System.in);

    int n &#61; Integer.parseInt(sc.nextLine());

    String[][] records &#61; new String[n][];
    for (int i &#61; 0; i &lt; n; i&#43;&#43;) {
      records[i] &#61; sc.nextLine().split(&#34; &#34;);
    }

    getResult(n, records);
  }

  public static void getResult(int n, String[][] records) {
    for (int i &#61; 0; i &lt; n; i&#43;&#43;) {
      System.out.println(isAward(records[i]));
    }
  }

  public static boolean isAward(String[] record) {
    // 总缺勤次数
    int absent &#61; 0;

    // 滑窗内正常上班的次数
    int present &#61; 0;

    // 记录前一次的考勤记录
    String preRecord &#61; &#34;&#34;;

    for (int i &#61; 0; i &lt; record.length; i&#43;&#43;) {
      if (i &gt;&#61; 7) {
        // 滑窗长度最大为7&#xff0c;如果超过7&#xff0c;则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
        // 如果失去部分是present&#xff0c;则更新滑窗内present次数
        if (&#34;present&#34;.equals(record[i - 7])) present--;
      }

      // 当前的考勤记录
      String curRecord &#61; record[i];

      switch (curRecord) {
        case &#34;absent&#34;:
          // 缺勤不超过一次
          if (&#43;&#43;absent &gt; 1) return false;
          break;
        case &#34;late&#34;:
        case &#34;leaveearly&#34;:
          // 没有连续的迟到/早退
          if (&#34;late&#34;.equals(preRecord) || &#34;leaveearly&#34;.equals(preRecord)) return false;
          break;
        case &#34;present&#34;:
          present&#43;&#43;;
          break;
      }

      preRecord &#61; curRecord;

      // 任意连续7次考勤&#xff0c;缺勤/迟到/早退不超过3次, 相当于判断&#xff1a; 滑窗长度 - present次数 &lt;&#61; 3
      int window_len &#61; Math.min(i &#43; 1, 7); // 滑窗长度
      if (window_len - present &gt; 3) return false;
    }

    return true;
  }
}
</code></pre> 
<p></p> 
<h4>Python算法源码</h4> 
<pre><code class="language-python"># 输入获取
n &#61; int(input())
records &#61; [input().split() for _ in range(n)]


def isAward(record):
    # 总缺勤次数
    absent &#61; 0

    #  滑窗内正常上班的次数
    present &#61; 0

    late_leaveearly &#61; (&#34;late&#34;, &#34;leaveearly&#34;)

    # 前一次的考勤记录
    preRecord &#61; &#34;&#34;

    for i in range(len(record)):
        # 滑窗长度最大为7&#xff0c;如果超过7&#xff0c;则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
        # 如果失去部分是present&#xff0c;则更新滑窗内present次数
        if i &gt;&#61; 7:
            if &#34;present&#34; &#61;&#61; record[i-7]:
                present -&#61; 1

        # 当前的考勤记录
        curRecord &#61; record[i]

        if &#34;absent&#34; &#61;&#61; curRecord:
            absent &#43;&#61; 1
            # 缺勤超过1次&#xff0c;则拿不到全勤奖
            if absent &gt; 1:
                return &#34;false&#34;
        elif curRecord in late_leaveearly and preRecord in late_leaveearly:
            # 连续的迟到/早退&#xff0c;则拿不到全勤奖
            return &#34;false&#34;
        elif &#34;present&#34; &#61;&#61; curRecord:
            present &#43;&#61; 1

        preRecord &#61; curRecord

        # 任意连续7次考勤&#xff0c;缺勤/迟到/早退不超过3次, 相当于判断&#xff1a; 滑窗长度 - present次数 &lt;&#61; 3
        window_len &#61; min(i&#43;1, 7)  # 滑窗长度
        if window_len - present &gt; 3:
            return &#34;false&#34;

    return &#34;true&#34;


# 算法入口
def getResult():
    for record in records:
        print(isAward(record))


# 算法调用
getResult()
</code></pre> 
<p></p> 
<h4 style="background-color:transparent;">C算法源码</h4> 
<pre><code class="language-cpp">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#define MIN(a, b) ((a) &lt; (b) ? (a) : (b))

int isAward(char records[][15], int records_size);
int eq(char *a, char *b);

int main() {
    int n;
    scanf(&#34;%d&#34;, &amp;n);

    for (int i &#61; 0; i &lt; n; i&#43;&#43;) {
        char records[10000][15];
        int records_size &#61; 0;

        while(scanf(&#34;%s&#34;, records[records_size&#43;&#43;])) {
            if(getchar() !&#61; &#39; &#39;) break;
        }

        puts(isAward(records, records_size) ? &#34;true&#34; : &#34;false&#34;);
    }

    return 0;
}

int isAward(char records[][15], int records_size) {
    // 总缺勤次数
    int absent &#61; 0;

    // 滑窗内正常上班的次数
    int present &#61; 0;

    // 记录前一次的考勤记录
    char *preRecord &#61; &#34;&#34;;

    for (int i &#61; 0; i &lt; records_size; i&#43;&#43;) {
        // 滑窗长度最大为7&#xff0c;如果超过7&#xff0c;则滑窗的左边界需要右移, 滑窗失去的部分record[i - 7]
        // 如果失去部分是present&#xff0c;则更新滑窗内present次数
        if (i &gt;&#61; 7) {
            if(eq(&#34;present&#34;, records[i-7])) {
                present--;
            }
        }

        // 当前的考勤记录
        char *curRecord &#61; records[i];

        if (eq(curRecord, &#34;absent&#34;)) {
            // 缺勤不超过一次
            if (&#43;&#43;absent &gt; 1) return 0;
        } else if (eq(curRecord, &#34;late&#34;) || eq(curRecord, &#34;leaveearly&#34;)) {
            // 没有连续的迟到/早退
            if (eq(preRecord, &#34;late&#34;) || eq(preRecord, &#34;leaveearly&#34;)) return 0;
        } else if (eq(curRecord, &#34;present&#34;)) {
            present&#43;&#43;;
        }

        preRecord &#61; curRecord;

        // 任意连续7次考勤&#xff0c;缺勤/迟到/早退不超过3次, 相当于判断&#xff1a; 滑窗长度 - present次数 &lt;&#61; 3
        int window_len &#61; MIN(i &#43; 1, 7);
        if (window_len - present &gt; 3) return 0;
    }

    return 1;
}

int eq(char *a, char *b) {
    return strcmp(a, b) &#61;&#61; 0 ? 1 : 0;
}
</code></pre>
                </div>
        </div>
        <div id="treeSkill"></div>
        <div id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"></div>
    <script>
  $(function() {
    setTimeout(function () {
      var mathcodeList = document.querySelectorAll('.htmledit_views img.mathcode');
      if (mathcodeList.length > 0) {
        for (let i = 0; i < mathcodeList.length; i++) {
          if (mathcodeList[i].naturalWidth === 0 || mathcodeList[i].naturalHeight === 0) {
            var alt = mathcodeList[i].alt;
            alt = '\\(' + alt + '\\)';
            var curSpan = $('<span class="img-codecogs"></span>');
            curSpan.text(alt);
            $(mathcodeList[i]).before(curSpan);
            $(mathcodeList[i]).remove();
          }
        }
        MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
      }
    }, 1000)
  });
</script>
</div></html>